#include <stdio.h>
#include "ShaderManager.h"
#include "RenderManager.h"

#include <windows.h>

static void Display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//glClear(GL_COLOR_BUFFER_BIT);
	RenderManager::Instance()->Draw();
	glutSwapBuffers();
}

inline int64_t GetTimeMS()
{
	return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}

static void idle(void)
{
	static int64_t lastTime = GetTimeMS();
	int64_t past = GetTimeMS() - lastTime;
	static int interval = 1000 / 60;
	if (past < interval)
	{
		Sleep(interval - past);
	}
	lastTime = GetTimeMS();
	RenderManager::Instance()->Idle();
	glutPostRedisplay();
}

static void reshape(int width, int height)
{
	double aspectRatio = (float)width / (float)height;
	double fieldOfView = 40.0; /* Degrees */

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(fieldOfView, aspectRatio, 1.0f, 100.0f);
	glViewport(0, 0, width, height);
}

static void InitializeGlut(int* argc, char* argv[])
{
	glutInitWindowSize(400, 400);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	glutInit(argc, argv);
	glutCreateWindow(argv[0]);
	glutDisplayFunc(Display);
	glutIdleFunc(idle);
	//glutReshapeFunc(reshape);
	//requestSynchronizedSwapBuffers();
	glClearColor(0.1, 0.1, 0.1, 0);  /* Gray background. */
	glEnable(GL_DEPTH_TEST);         /* Hidden surface removal. */
	//glClearColor(1, 1, 1, 1);  /* White background */
}

int main(int argc, char* argv[])
{
	InitializeGlut(&argc, argv);

	CGcontext Context = cgCreateContext();
	ShaderManager::Instance()->Initialize(Context);

	glutMainLoop();

	ShaderManager::Instance()->Release();
	cgDestroyContext(Context);

	return 0;
}